module ProgramCounterSelector(
	
	//PCcurrent 
	input	[31:0]	i_PCS_PCcurrent,
	//COMMIT
	input	[31:0]	i_PCS_EPC,	
	input	[7:0]	i_PCS_EXCCODE,	//{[7]valid, [6]isERET, [5]isDelaySlot, [4:0]ExcCode}
	input	[34:0]	i_PCS_BRANCH,	//{[34]BranchEnable, [33:32]BranchTaken, [31:0]BranchTarget}
	input			i_PCS_interrupt,
	//PreDecoder
	input			i_PCS_PC4,
	//BTB
	input			i_PCS_BTBhit,
	input	[1:0]	i_PCS_BTBcounter,
	input	[31:0]	i_PCS_BTBtarget,
	//PCnext
	output	[31:0]	o_PCS_PCnext
	
);
	
	wire	IR	 = i_PCS_interrupt;
	wire	EXC	 = i_PCS_EXCCODE[7];
	wire	ERET = i_PCS_EXCCODE[6];
	wire	BranchError = i_PCS_BRANCH[34] && ^i_PCS_BRANCH[33:32];
	wire	BranchTarget = i_PCS_BRANCH[31:0];
	
	assign	o_PCS_PCnext = ((ERET) ? i_PCS_EPC :
								((EXC|IR) ? 32'hbfc0_0380 :
									((BranchError) ? BranchTarget :
										((i_PCS_PC4) ? i_PCS_PCcurrent+32'd4 :
											((i_PCS_BTBhit&&i_PCS_BTBcounter[1]) ? i_PCS_BTBtarget :
												i_PCS_PCcurrent+32'd4;
											)
										)
									)
								)
							)
endmodule